<template>
  <div id="elesign" class="elesign">
    <div class="ele-control">
      <el-button class="btn-outline-dark" @click="removeSignature">
        删除签章</el-button
      >
      <el-button class="btn-outline-dark" @click="clearSignature">
        清除所有签章</el-button
      >
      <el-button class="btn-outline-dark" @click="submitSignature"
        >提交所有签章信息</el-button
      >
    </div>
    <el-row class="content">
      <el-col :span="4" class="left">
        <div class="left-title">我的印章</div>
        <draggable
          v-model="mainImagelist"
          :group="{ name: 'itext', pull: 'clone' }"
          :sort="false"
          @end="end"
        >
          <transition-group type="transition">
            <li
              v-for="item in mainImagelist"
              :key="item"
              class="item"
              style="text-align: center"
            >
              <img :src="item" width="100%;" height="100%" class="imgstyle" />
            </li>
          </transition-group>
        </draggable>
      </el-col>
      <el-col :span="16" style="text-align: center" class="pCenter">
        <canvas id="the-canvas" />
        <!-- 盖章部分 -->
        <canvas id="ele-canvas"></canvas>
      </el-col>

      <el-col :span="3" class="right">
        <div class="left-title">任务信息</div>
        <div style="text-align: center">
          <div>
            <div class="right-item">
              <div class="right-item-title">文件主题</div>
              <div class="detail-item-desc">{{ taskInfo.title }}</div>
            </div>
            <div class="right-item">
              <div class="right-item-title">发起方</div>
              <div class="detail-item-desc">{{ taskInfo.uname }}</div>
            </div>
            <div class="right-item">
              <div class="right-item-title">截止时间</div>
              <div class="detail-item-desc">{{ taskInfo.endtime }}</div>
            </div>
          </div>
        </div>
      </el-col>
    </el-row>
    <div class="page">
      <el-button class="btn-outline-dark" @click="prevPage">上一页</el-button>
      <el-button class="btn-outline-dark" @click="nextPage">下一页</el-button>
      <el-button class="btn-outline-dark"
        >{{ pageNum }}/{{ numPages }}页</el-button
      >
      <el-input-number
        style="margin: 0 10px; border-radius: 10px"
        class="btn-outline-dark pageTo"
        v-model="pageNum"
        :min="1"
        :max="numPages"
        :controls="false"
        label="输入页码"
      ></el-input-number>
      <el-button class="btn-outline-dark" @click="cutover">跳转</el-button>
    </div>
  </div>
</template>

<script>
import { fabric } from 'fabric'
let pdfjsLib = require('pdfjs-dist/legacy/build/pdf.js')
import workerSrc from 'pdfjs-dist/legacy/build/pdf.worker.entry'
import draggable from 'vuedraggable'

pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc
let localStorage = window.localStorage
export default {
  name: 'MyPdfSignature',
  props: {
    signatureForm: {
      type: Object,
      default: null,
    },
  },
  components: { draggable },
  data() {
    return {
      //pdf预览
      pdfUrl: '',
      pdfDoc: null,
      numPages: 1,
      pageNum: 1,
      scale: 2.2,
      pageRendering: false,
      pageNumPending: null,
      sealUrl: '',
      signUrl: '',
      canvas: null,
      ctx: null,
      canvasEle: null,
      whDatas: null,
      mainImagelist: [],
      taskInfo: {},
      form: {},
    }
  },
  computed: {},
  created() {
    localStorage.removeItem('signs')
    // pdf文件
    this.pdfurl = 'http://localhost:8080/show.pdf'
    // 盖章图片列表
    this.mainImagelist = [
      'http://localhost:8080/sign.png',
      'http://localhost:8080/seal.png',
    ]
  },
  mounted() {
    // 初始化PDF文件
    this.showpdf('http://localhost:8080/show.pdf')
  },
  methods: {
    //pdf预览
    renderPage(num) {
      let _this = this
      this.pageRendering = true
      return this.pdfDoc.getPage(num).then(page => {
        let viewport = page.getViewport({ scale: _this.scale }) //设置视口大小
        _this.canvas.height = viewport.height
        _this.canvas.width = viewport.width

        // Render PDF page into canvas context
        let renderContext = {
          canvasContext: _this.ctx,
          viewport: viewport,
        }
        let renderTask = page.render(renderContext)
        // Wait for rendering to finish
        renderTask.promise.then(() => {
          _this.pageRendering = false
          if (_this.pageNumPending !== null) {
            // New page rendering is pending
            this.renderPage(_this.pageNumPending)
            _this.pageNumPending = null
          }
        })
      })
    },
    queueRenderPage(num) {
      if (this.pageRendering) {
        this.pageNumPending = num
      } else {
        this.renderPage(num)
      }
    },
    prevPage() {
      this.confirmSignature()
      if (this.pageNum <= 1) {
        return
      }
      this.pageNum--
    },
    nextPage() {
      this.confirmSignature()
      if (this.pageNum >= this.numPages) {
        return
      }
      this.pageNum++
      //this.commonSign(this.pageNum);
    },
    handleChange(currentValue, oldValue) {
      this.confirmSignature()
      //console.log("当前",currentValue);
      //console.log("原值",oldValue);
    },
    cutover() {
      this.confirmSignature()
    },
    //渲染pdf，到时还会盖章信息，在渲染时，同时显示出来，不应该在切换页码时才显示印章信息
    showpdf(pdfUrl) {
      let caches = JSON.parse(localStorage.getItem('signs')) //获取缓存字符串后转换为对象
      if (caches != null) {
        let datas = caches[this.pageNum]
        if (datas != null && datas != undefined) {
          for (let index in datas) {
            this.addSeal(
              datas[index].sealUrl,
              datas[index].left,
              datas[index].top,
              datas[index].index
            )
          }
        }
      }
      this.$nextTick(() => {
        this.canvas = document.getElementById('the-canvas')
        this.ctx = this.canvas.getContext('2d')
        pdfjsLib
          .getDocument({
            url: pdfUrl,
            rangeChunkSize: 65536,
            disableAutoFetch: false,
          })
          .promise.then(pdfDoc_ => {
            // debugger
            this.pdfDoc = pdfDoc_
            this.numPages = this.pdfDoc.numPages
            this.renderPage(this.pageNum).then(() => {
              this.renderPdf({
                width: this.canvas.width,
                height: this.canvas.height,
              })
            })
            this.commonSign(this.pageNum, true)
          })
      })
    },
    /**
     *  盖章部分开始
     */
    // 设置绘图区域宽高
    renderPdf(data) {
      this.whDatas = data
    },
    // 生成绘图区域
    renderFabric() {
      let canvaEle = document.querySelector('#ele-canvas')
      let pCenter = document.querySelector('.pCenter')
      let theCansvas = document.getElementById('the-canvas')
      let upperEle = document.querySelector('.upper-canvas')

      console.log(theCansvas)
      canvaEle.width = theCansvas.clientWidth
      canvaEle.height = theCansvas.clientHeight

      this.canvasEle = new fabric.Canvas(canvaEle)
      let container = document.querySelector('.canvas-container')
      container.style.position = 'absolute'
      container.style.top = '0px'

      //20230323
      canvaEle.width = container.clientWidth
      canvaEle.height = container.clientHeight

      pCenter.style.width = theCansvas.clientWidth
      pCenter.style.height = theCansvas.clientHeight
      //放开
    },
    // 相关事件操作哟
    canvasEvents() {
      // 拖拽边界 不能将图片拖拽到绘图区域外
      this.canvasEle.on('object:moving', function (e) {
        var obj = e.target
        // if object is too big ignore
        if (
          obj.currentHeight > obj.canvas.height ||
          obj.currentWidth > obj.canvas.width
        ) {
          return
        }
        obj.setCoords()
        // top-left  corner
        if (obj.getBoundingRect().top < 0 || obj.getBoundingRect().left < 0) {
          obj.top = Math.max(obj.top, obj.top - obj.getBoundingRect().top) - 50
          obj.left =
            Math.max(obj.left, obj.left - obj.getBoundingRect().left) - 50
        }
        // bot-right corner
        if (
          obj.getBoundingRect().top + obj.getBoundingRect().height >
            obj.canvas.height ||
          obj.getBoundingRect().left + obj.getBoundingRect().width >
            obj.canvas.width
        ) {
          obj.top =
            Math.min(
              obj.top,
              obj.canvas.height -
                obj.getBoundingRect().height +
                obj.top -
                obj.getBoundingRect().top
            ) - 50
          obj.left =
            Math.min(
              obj.left,
              obj.canvas.width -
                obj.getBoundingRect().width +
                obj.left -
                obj.getBoundingRect().left
            ) - 50
        }
      })
    },
    // 添加公章
    addSeal(sealUrl, left, top, index) {
      console.log(1, sealUrl)
      console.log(2, left)
      console.log(3, top)
      console.log(4, index)
      //   debugger
      // 创建实例对象
      var img = new Image()
      // 图片地址
      img.src = sealUrl
      let imgstyle = document.querySelector('.imgstyle')
      let proportion = imgstyle.clientWidth / img.width
      //let scaleX = 0.8;
      //let scaleY = 0.8;
      fabric.Image.fromURL(sealUrl, oImg => {
        oImg.set({
          left: left - (oImg.width / 2) * proportion,
          top: top - (oImg.height / 2) * proportion,
          // angle: 10,
          //left: left,
          //top: top,
          leftX: left,
          topy: top,
          scaleX: proportion,
          scaleY: proportion,
          index: index,
        })
        oImg.scale(proportion) //图片缩小一
        this.canvasEle.add(oImg)
      })
    },
    // 删除签章
    removeSignature() {
      this.canvasEle.remove(this.canvasEle.getActiveObject())
    },
    //翻页展示盖章信息
    commonSign(pageNum, isFirst = false) {
      //   debugger
      if (isFirst == false) this.canvasEle.remove(this.canvasEle.clear()) //清空页面所有签章
      let caches = JSON.parse(localStorage.getItem('signs')) //获取缓存字符串后转换为对象
      if (caches == null) return false
      let datas = caches[this.pageNum]
      if (datas != null && datas != undefined) {
        for (let index in datas) {
          console.log('回显', datas[index])
          this.addSeal(
            datas[index].sealUrl,
            datas[index].leftx,
            datas[index].topy,
            datas[index].index
          )
        }
      }
    },
    //确认签章位置并保存到缓存
    confirmSignature() {
      //   debugger
      let data = this.canvasEle.getObjects() //获取当前页面内的所有签章信息
      let caches = JSON.parse(localStorage.getItem('signs')) //获取缓存字符串后转换为对象

      let signDatas = {} //存储当前页的所有签章信息
      let i = 0
      // let sealUrl = '';
      for (var val of data) {
        console.log('确定', val)
        signDatas[i] = {
          width: val.width,
          height: val.height,
          top: val.top,
          left: val.left,
          topy: val.topy,
          leftx: val.leftX,
          angle: val.angle,
          translateX: val.translateX,
          translateY: val.translateY,
          scaleX: val.scaleX,
          scaleY: val.scaleY,
          pageNum: this.pageNum,
          sealUrl: this.mainImagelist[val.index],
          index: val.index,
        }
        i++
      }
      if (caches == null) {
        caches = {}
        caches[this.pageNum] = signDatas
      } else {
        caches[this.pageNum] = signDatas
      }
      localStorage.setItem('signs', JSON.stringify(caches)) //对象转字符串后存储到缓存
    },
    //提交数据
    submitSignature() {
      this.confirmSignature()
      let caches = localStorage.getItem('signs')
      if (caches.length <= 8) {
        this.msgSuccess('请完成盖章后提交！！')
        return
      }
      this.form.signs = caches

      let eleCanvas = document.querySelector('#ele-canvas')
      this.form.pdfWidth = eleCanvas.width
      this.form.pdfHeight = eleCanvas.height
      // 给后端传递盖章数据
      console.log(this.form)

      return false
    },
    //清空数据
    clearSignature() {
      this.canvasEle.remove(this.canvasEle.clear()) //清空页面所有签章
      localStorage.removeItem('signs') //清除缓存
    },
    dragBug(evt) {
      var e = evt || window.event
      var chosen = document.querySelector('.item')
      chosen.style.top = e.item.offsetTop + 'px'
    },
    end(e) {
      let newIndex = e.newIndex
      this.addSeal(
        this.mainImagelist[e.newDraggableIndex],
        e.originalEvent.layerX,
        e.originalEvent.layerY,
        e.newDraggableIndex
      )
    },
    //设置PDF预览区域高度
    setPdfArea() {
      this.pdfUrl = this.signatureForm.fileUrl
      this.pdfurl = res.data.data.pdfurl
      this.$nextTick(() => {
        this.showpdf(this.pdfUrl) //接口返回的应该还有盖章信息，不只是pdf
      })
    },
  },
  watch: {
    whDatas: {
      handler() {
        const loading = this.$loading({
          lock: true,
          text: 'Loading',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)',
        })
        if (this.whDatas) {
          loading.close()
          this.renderFabric()
          this.canvasEvents()
          let eleCanvas = document.querySelector('#ele-canvas')
          eleCanvas.style = 'border:1px solid #5ea6ef'
        }
      },
    },
    pdfUrl: function (val) {
      this.$nextTick(() => {
        this.showpdf(val)
      })
    },
    pageNum: function () {
      this.commonSign(this.pageNum)
      this.queueRenderPage(this.pageNum)
    },
  },
}
</script>

<style scoped lang="less">
/*pdf部分*/

.pCenter {
  overflow: auto;
  position: sticky;
  overflow-x: hidden;
  height: 100%;
  margin-bottom: 20px;
  padding: 0 15px 0 0px;
}

#the-canvas {
  width: 100%;
}

html:fullscreen {
  background: white;
}

.elesign {
  display: flex;
  flex: 1;
  flex-direction: column;
  position: relative;
  /* padding-left: 180px; */
  height: 100%;
  margin: auto;
  // height:600px;
  // overflow: auto;
  /* width:600px; */
  .left {
    position: sticky;
    left: 0;
    top: 0;
    height: 100%;
    overflow-y: auto;
    margin-right: 0.5%;
  }

  .right {
    position: sticky;
    right: 0;
    top: 0;
    height: 100%;
    margin-left: 0.5%;
  }
}

.content {
  height: calc(100% - 48px - 48px);
}

.page {
  position: sticky;
  text-align: center;
  margin: 0 auto;
  display: flex;
  justify-content: center;
  bottom: 0;
  background-color: #fff;
  margin-top: 16px;
}

#ele-canvas {
  /* border: 1px solid #5ea6ef; */
  overflow: hidden;
}

.ele-control {
  text-align: center;
  position: sticky;
  background-color: #fff;
  vertical-align: middle;
  top: 0;
  z-index: 99;
  margin-bottom: 16px;
}

#page-input {
  width: 7%;
}

@keyframes ani-demo-spin {
  from {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(180deg);
  }
  to {
    transform: rotate(360deg);
  }
}

/* .loadingclass{
    position: absolute;
    top:30%;
    left:49%;
    z-index: 99;
} */
.left {
  position: absolute;
  top: 32px;
  left: -5px;
  padding: 5px 5px;
  /*border: 1px solid #eee;*/
  /*border-radius: 4px;*/
}

.left-title {
  text-align: center;
  padding-bottom: 10px;
}

li {
  list-style-type: none;
  padding: 10px;
}

.imgstyle {
  vertical-align: middle;
  width: 130px;
  border: solid 1px #e8eef2;
  //background-image: url("tuo.png");
  background-repeat: no-repeat;
}

.right {
  position: absolute;
  top: 7px;
  right: -177px;
  padding-bottom: 20px;
  /*border: 1px solid #eee;*/
  /*border-radius: 4px;*/
}

.right-item {
  margin-bottom: 15px;
  margin-left: 10px;
  text-align: right;
}

.right-item-title {
  color: #777;
  height: 20px;
  line-height: 20px;
  font-size: 12px;
  font-weight: 400;
  text-align: left !important;
}

.detail-item-desc {
  color: #333;
  line-height: 20px;
  width: 100%;
  font-size: 12px;
  display: inline-block;
  text-align: left;
}

.pageTo {
  width: 115px;
}

.btn-outline-dark {
  color: #0f1531;
  background-color: transparent;
  background-image: none;
}

.btn-outline-dark:hover {
  color: #fff;
  background-color: #3e4b5b;
  border-color: #3e4b5b;
}
</style>
